我們在之前文章介紹了MVP與MVVM,看起來兩者用哪一個來做UI的架構都可以寫Unit test,但是到底要用哪個來寫mobile application比較好呢?關於這點大家也可以在網路上找到很多文章來說誰好誰不好,但我這邊不會很武斷的告訴大家說誰就比較好。這兩種設計模式各有各的優缺點,下圖說明我們從什麼都不用的寫法,直接在Activity裡面寫邏輯function也在function內直接引用UI元件,到使用MVP及MVVM的不同。
再來複習一下依賴反轉原則DIP,UI使用Presenter,Presenter只知道UI的抽象但不知道細節,所以Presentner的邏輯可以被不同UI使用,而不會只能服務一個UI。
明顯的好處是設計結構簡單,它用一個依賴反轉原則的概念把高層的UI跟低層的Presenter邏輯切開來,只要對View建立一個interface和把邏輯規畫寫在Presenter class裡就可以開始寫了,不論是寫Android,IOS或是其他平台的application,MVP都是一個很好練習上手的模式,我們不用其它Library的幫助,可以保持程式的乾淨及易於理解的架構。所以一開始想學單元測試的朋友不妨可以從這裡開始綀習,先把MVP開發application的習慣建立起來再來寫unit test會事半功倍。但缺點就是如上圖所示,被驗證者是View的interface,所以你的Presenter必須要去參考View的實體,之前已經提過會有memory leak的問題。
MVVM把Presenter改成用Oberver pattern的方式來寫,使我們得到的第一個好處就是把View會在Presenter被參照導致memory leak的問題改進,UI的reference完全消失在邏輯層的ViewModel不被呼叫。在實際開發中我有一段時間常遇到Presenter裡的View不見的問題,當然有一些trick的手法去可以片面解決這個問題,但架構在MVP下等於是隱藏問題不是解決問題,這時候用MVVM就可以從根本解決問題。
順帶一提MVVM的特點還有View與ViewModel的連結使用Data binding的方式,可以簡少我們在程式碼中對UI元件的引用,在Layout xml的檔案中就可以直接observe ViewModel的變化對UI直接做更新,而不用回傳到Activity來update UI,不過在我們的範例沒介紹這一部份因為這不是單元測試關注的部份。但這是優點也是缺點,因為實際的運作是靠SDK的library在背後產生許多boilerplate code也會讓你build出來的codebase長的更肥大,只是你沒看見而已,但是我們看得到的好處就是Activity裡對UI做設定的code大量減少。
MVVM看起來非常完美,我們應該毫不考慮的直接選用它來做為架構,雖然它有一些小缺點,但是在google大力的支援下有許多方便的寫法。從單元測試的角度來看兩者其實都是可以被測試的架構,如果你是尚未接觸過MVP或MVVM的人可以先從MVP開始,如果你已經很熟悉MVP又要開始新的task那不妨就從MVVM開始學習。
說了好像等於沒講,因為只要你遵循這些設計模式單元測試都是可以被執行的,大家不用糾結在哪個設計模式,黑貓白貓會抓老鼠的就是好貓。